﻿using Abp.Dependency;
using Abp.Events.Bus.Handlers;
using AVIS.OutBound.AWD;
using AVIS.OutBound.CarGroups;
using AVIS.OutBound.Cities;
using AVIS.OutBound.Orders;
using AVIS.OutBound.RateCodes;
using AVIS.OutBound.Regions;
using AVIS.OutBound.Stores;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AVIS.OutBound.Notify
{
    /// <summary>
    /// 消息通知的相关事件处理
    /// </summary>
    public class NotifyEventHandler :
        IEventHandler<OrderCanceledEventData>,
        IEventHandler<OrderSubmittedEventData>,
        ITransientDependency
    {
        #region 构造函数
        private readonly INotifyManager _notifyManager;
        private readonly AWDManager _awdManager;
        private readonly IRateCodeManager _rateCodeManager;
        private readonly IStoreManager _storeManager;
        private readonly ICityManager _cityManager;

        public NotifyEventHandler(
            INotifyManager notifyManager,
            IStoreManager storeManager,
            IRateCodeManager rateCodeManager,
            ICityManager cityManager,
            AWDManager awdManager
            )
        {
            _notifyManager = notifyManager;
            _awdManager = awdManager;
            _storeManager = storeManager;
            _rateCodeManager = rateCodeManager;
            _cityManager = cityManager;
        }
        #endregion

        /// <summary>
        /// 订单已取消的事件处理：异步发送邮件和短信
        /// </summary>
        /// <param name="eventData"></param>
        public void HandleEvent(OrderCanceledEventData eventData)
        {
            var order = eventData.Order;
            order.PickUpStore = _storeManager.GetStoreByCode(order.PickUpStoreCode);
            order.ReturnStore = _storeManager.GetStoreByCode(order.ReturnStoreCode);

            var templateParameters = order.Surname + " " + order.Firstname + OutBoundConsts.SysSeparator;
            templateParameters += order.OrderNo + OutBoundConsts.SysSeparator;
            templateParameters += order.PickupDateTime.ToString("dddd", new System.Globalization.CultureInfo("zh-cn")) + "," + order.PickupDateTime.ToString("yyyy年MM月dd日 HH:mm:ss") + OutBoundConsts.SysSeparator;
            templateParameters += order.ReturnDateTime.ToString("dddd", new System.Globalization.CultureInfo("zh-cn")) + "," + order.ReturnDateTime.ToString("yyyy年MM月dd日 HH:mm:ss") + OutBoundConsts.SysSeparator;
            templateParameters += order.PickUpStore.CNName + order.PickUpStore.LocationAddress + OutBoundConsts.SysSeparator;
            templateParameters += order.ReturnStore.CNName + order.ReturnStore.LocationAddress + OutBoundConsts.SysSeparator;
            templateParameters += order.CarGroup?.ModelName + OutBoundConsts.SysSeparator;
            _notifyManager.SendMail(order.Email, "OB订单取消", templateParameters);

            _notifyManager.SendSMS(order.Telephone, "国际订单取消", order.OrderNo);
        }

        /// <summary>
        /// 订单已提交的事件处理：异步发送邮件和短信
        /// </summary>
        /// <param name="eventData"></param>
        public void HandleEvent(OrderSubmittedEventData eventData)
        {
            var order = eventData.Order;

            var emailParameters = GetOrderSuccessMailParameters(order);
            _notifyManager.SendMail(order.Email, "OB订单确认", emailParameters);

            var TempletName = eventData.IsNewOrder ? "国际订单确认" : "国际订单修改";
            var smsParameters = GetOrderSuccessMessageParameters(order);
            _notifyManager.SendSMS(order.Telephone, TempletName, smsParameters);
        }

        /// <summary>
        /// 获取订单成功的邮件内容参数
        /// </summary>
        /// <returns></returns>
        private string GetOrderSuccessMailParameters(Order order)
        {
            // 获取真实的AWD号，一般国内的AWD号是以CN开头的
            var realAWD = _awdManager.GetRealAWDCode(order.AWD);

            // 处理订单中的取还车门店信息
            order.PickUpStore = _storeManager.GetStoreByCode(order.PickUpStoreCode);
            order.ReturnStore = _storeManager.GetStoreByCode(order.ReturnStoreCode);

            StringBuilder sb = new StringBuilder();
            sb.Append(order.Surname + " " + order.Firstname + OutBoundConsts.SysSeparator);
            sb.Append(order.OrderNo + OutBoundConsts.SysSeparator);
            sb.Append(order.RentalLength + OutBoundConsts.SysSeparator);
            sb.Append(order.Address + OutBoundConsts.SysSeparator);
            sb.Append(order.PickUpStore.CNName + OutBoundConsts.SysSeparator);
            sb.Append(order.PickUpStore.DayOpenTime(order.PickupDateTime) + OutBoundConsts.SysSeparator);
            sb.Append(order.PickUpStore.Telephone + OutBoundConsts.SysSeparator);
            sb.Append(order.PickupDateTime.ToString("dddd", new System.Globalization.CultureInfo("zh-cn")) + "," + order.PickupDateTime.ToString("yyyy年MM月dd日 HH:mm") + OutBoundConsts.SysSeparator);
            sb.Append(order.ReturnStore.CNName + OutBoundConsts.SysSeparator);
            sb.Append(order.ReturnStore.DayOpenTime(order.ReturnDateTime) + OutBoundConsts.SysSeparator);
            sb.Append(order.ReturnStore.Telephone + OutBoundConsts.SysSeparator);
            sb.Append(order.ReturnDateTime.ToString("dddd", new System.Globalization.CultureInfo("zh-cn")) + "," + order.ReturnDateTime.ToString("yyyy年MM月dd日 HH:mm") + OutBoundConsts.SysSeparator);
            sb.Append(order.CarGroup.ModelName + OutBoundConsts.SysSeparator);
            sb.Append(order.Amount.ToString("0.00") + order.CurrencyCode + OutBoundConsts.SysSeparator);
            sb.Append(OutBoundConsts.SysSeparator); // 人民币价格，暂时为空
            sb.Append(GetPriceIncludeContent(order.CarGroup.PriceInclue) + OutBoundConsts.SysSeparator);

            var RatePackage = _rateCodeManager.GetRateCode(order);
            if (RatePackage != null)
            {
                sb.Append(RatePackage.Name + OutBoundConsts.SysSeparator);
                sb.Append(GetRateContent(RatePackage) + OutBoundConsts.SysSeparator);
            }
            else
            {
                sb.Append(OutBoundConsts.SysSeparator);
                sb.Append(OutBoundConsts.SysSeparator);
            }
            sb.Append(order.EquipmentDesc + OutBoundConsts.SysSeparator);

            // 地区编号（简写，美国只返回 US，加拿大只返回 CA）
            string regionShortCode = new Region { RegionCode = order.PickUpStore.RegionCode }.RegionShortCode;
            sb.Append(regionShortCode + OutBoundConsts.SysSeparator);
            sb.Append(order.CarGroup.ModelCode + OutBoundConsts.SysSeparator);
            sb.Append(order.PickUpStore.LocationAddress + OutBoundConsts.SysSeparator);
            sb.Append(order.ReturnStore.LocationAddress + OutBoundConsts.SysSeparator);
            sb.Append(order.FTNNumber + OutBoundConsts.SysSeparator);
            sb.Append(order.WizardNum + OutBoundConsts.SysSeparator);
            sb.Append((string.IsNullOrEmpty(realAWD) ? realAWD : realAWD.Replace(realAWD.Substring(realAWD.Length - 5, 4), "****")) + OutBoundConsts.SysSeparator);

            sb.Append(order.CouponNum + OutBoundConsts.SysSeparator);
            sb.Append(order.FlightNumber);

            return sb.ToString();
        }

        /// <summary>
        /// 获取订单成功的短信内容参数
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        private string GetOrderSuccessMessageParameters(Order order)
        {
            // 获取真实的AWD号，一般国内的AWD号是以CN开头的
            var realAWD = _awdManager.GetRealAWDCode(order.AWD);

            // 处理订单中的取还车门店信息
            order.PickUpStore = _storeManager.GetStoreByCode(order.PickUpStoreCode);
            order.ReturnStore = _storeManager.GetStoreByCode(order.ReturnStoreCode);
            var pickUpCity = _cityManager.GetCity(order.PickUpStore.CityCode, order.PickUpRegionCode);
            var returnCity = _cityManager.GetCity(order.ReturnStore.CityCode, order.ReturnRegionCode);

            StringBuilder sb = new StringBuilder();
            sb.Append(order.OrderNo + OutBoundConsts.SysSeparator);
            sb.Append(order.PickupDateTime.ToString("yyyy年MM月dd日 HH:mm") + "～" + order.ReturnDateTime.ToString("yyyy年MM月dd日 HH:mm") + OutBoundConsts.SysSeparator);
            sb.Append(order.RentalLength + OutBoundConsts.SysSeparator);
            if (order.PickUpStoreCode != order.ReturnStoreCode)
            {
                sb.AppendFormat("取车门店：{0} {1}，电话：{2}，", pickUpCity.CNName, order.PickUpStore.CNName, order.PickUpStore.Telephone.Trim());
                sb.AppendFormat("还车门店：{0} {1}，电话：{2}{3}", returnCity.CNName, order.ReturnStore.CNName, order.ReturnStore.Telephone.Trim(), OutBoundConsts.SysSeparator);

                sb.AppendFormat("Pickup:{0} {1}，电话：{2},", pickUpCity.ENName, order.PickUpStore.ENName, order.PickUpStore.Telephone.Trim());
                sb.AppendFormat("Return:{0} {1}，电话：{2}{3}", returnCity.ENName, order.ReturnStore.ENName, order.ReturnStore.Telephone.Trim(), OutBoundConsts.SysSeparator);
            }
            else
            {
                sb.AppendFormat("取还车门店：{0} {1}，电话：{2}{3}", pickUpCity.CNName, order.PickUpStore.CNName, order.PickUpStore.Telephone.Trim(), OutBoundConsts.SysSeparator);
                sb.AppendFormat("Pickup/Return:{0} {1}，电话：{2}{3}", pickUpCity.ENName, order.PickUpStore.ENName, order.PickUpStore.Telephone.Trim(), OutBoundConsts.SysSeparator);
            }
            sb.Append(order.Amount.ToString("0.00") + order.CurrencyCode + " ");
            return sb.ToString();
        }

        /// <summary>
        /// 获取指定套餐的内容（用 <br/> 分割）
        /// </summary>
        /// <param name="package"></param>
        /// <returns></returns>
        private string GetRateContent(RateCode package)
        {
            var content = (string.IsNullOrEmpty(package.Content1) ? "" : "<br/>" + package.Content1) +
                            (string.IsNullOrEmpty(package.Content2) ? "" : "<br/>" + package.Content2) +
                            (string.IsNullOrEmpty(package.Content3) ? "" : "<br/>" + package.Content3) +
                            (string.IsNullOrEmpty(package.Content4) ? "" : "<br/>" + package.Content4) +
                            (string.IsNullOrEmpty(package.Content5) ? "" : "<br/>" + package.Content5) +
                            (string.IsNullOrEmpty(package.Content6) ? "" : "<br/>" + package.Content6);

            return content.StartsWith("<br/>") ? content.Remove(0, "<br/>".Length) : content;
        }

        private string GetPriceIncludeContent(PriceInclude priceInclude)
        {
            var sbDesc = new StringBuilder();
            foreach (var content in priceInclude.Contents)
            {
                sbDesc.AppendFormat("{0}<Br/>", content);
            }
            return sbDesc.ToString();
        }
    }
}
